﻿using Models.Common;
using Newtonsoft.Json;
using RabbitMQ.Client;
using RabbitMQ.Client.Events;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Utils_Base;
using Utils_ORM.MySql_IotWork;
using GateWayCommonService.Mq;
using GateWayCommonService.Device;

namespace GateWayCommonService.GateWay
{
    public class ServiceRabbitMQ_DeviceHelper
    {
        static ConnectionFactory factory = null;

        public static DateTime gateWayStartSystemTime = DateTime.Now;
        public static bool payBool = false;
        public void runPayMsg()
        {
            //while (payBool == false)
            //{
            //payMsg();
            //  Thread.Sleep(60 * 1000);
            // }

            do
            {
                Thread.Sleep(10 * 1000);
                if (payBool == false)
                {
                    payMsg();
                }

            } while (true);
        }
        static IConnection connectionPay = null;
        static IModel channelpay = null;
        static ConnectionFactory connectionFactoryPay = null;
        static string EXCHANGE_NAME = "my_exchange"; //要使用的exchange的名称
        static string EXCHANGE_TYPE = "topic"; //要使用的exchange的名称
        static string EXCHANGE_ROUTING_KEY = "my_routing_key.#"; //exchange使用的routing-key

        public void payMsg()
        {
            payBool = true;
            try
            {

                if (connectionPay != null && connectionPay.IsOpen)
                {
                    connectionPay.Close();
                    connectionPay.Dispose();

                };
                // int aa = 0;
                new UtilsFileHelper().deviceServer_WriteMessageAppend("payMsg 启动");
                string queuename = MQEventEnum.MQDevice_WorkServer_QueueName + UtilsMachineInfo.getMachineId();

                // string queuename = "queuename_hostServerIot_82c00007fc00470801421d243c7321d1";
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString() + "payMsg 启动 " + UtilsAppsetting.GetSettings("base:mqVirtualHost") + "--" + UtilsMachineInfo.getMachineId());

                connectionFactoryPay = ServiceRabbitMQ_Common.initFactory();
                //创建连接
                connectionPay = connectionFactoryPay.CreateConnection();
                //连接关闭的时候
                connectionPay.ConnectionShutdown += Connetion_ConnectionShutdown;
                //异常
                connectionPay.CallbackException += Connetion_CallbackException;
                if (channelpay == null || !channelpay.IsOpen)
                {
                    //创建通道
                    channelpay = connectionPay.CreateModel();
                    //channelpay.ExchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true, false, null);
                    ////声明一个队列
                    //channelpay.QueueDeclare(queuename, false, false, true, null);
                    ////将queue绑定至某个exchange。一个exchange可以绑定多个queue
                    //channelpay.QueueBind(queuename, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);
                }

                //事件基本消费者
                EventingBasicConsumer consumer = new EventingBasicConsumer(channelpay);

                //接收到消息事件
                consumer.Received += (ch, ea) =>
                {
                    string message = Encoding.Default.GetString(ea.Body.ToArray());
                    Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString() + $" ----------payMsg收到云mq消息--------start------");
                    Console.WriteLine($"{message}");
                    Console.WriteLine($" ----------payMsg收到云mq消息--------end------");

                    // Console.WriteLine($"收到该消息[{ea.DeliveryTag}] 延迟10s发送回执");

                    //new UtilsFileHelper().log_WriteMessageAppend("devicemessage", message);

                    //确认该消息已被消费
                    channelpay.BasicAck(ea.DeliveryTag, false);
                    if (gateWayStartSystemTime > DateTime.Now.AddSeconds(-10))
                    {
                        //不处理10秒前的垃圾记录
                    }
                    else
                    {
                        Task.Run(() =>
                        {
                            payEvent(message);

                        });
                    }
                    Thread.Sleep(50);
                    //先消费，后确认，免费处理事件出错，比如执行重启执令，这里无法消费
                };
                //启动消费者 设置为手动应答消息
                channelpay.BasicConsume(queuename, false, consumer);
                //                quere：队列名称；
                //noAck：消息的确认，True：消息读取自动排除，下次不会读取到；false 消息没有排除，一直存在；
                //consumer：消费者名称。
                //Console.ReadKey();
                //do { Thread.Sleep(30000); } while (true);
            }
            catch (Exception ex)
            {
                payBool = false;
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString() + $" Exception payMsg   end -------------------");
                Console.WriteLine("payMsg： Exception" + ex);

                if (null != channelpay)
                {
                    channelpay.Close();
                    channelpay.Dispose();
                    channelpay = null;
                }
                if (null != connectionPay)
                {
                    connectionPay.Close();
                    connectionPay.Dispose();
                    connectionPay = null;
                }

                new UtilsFileHelper().log_WriteMessageAppend(UtilsFileHelper.FILE_DEVICE_NAME + "_error", " payMsg 启动 Exception " + ex.ToString());
            }
            finally
            {
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString() + $" finally payMsg   end -------------------");

            }

        }


        private void Connetion_ConnectionShutdown(object sender, ShutdownEventArgs e)
        {//断开连接
         // Console.WriteLine("Connetion_ConnectionShutdown");
         //payMsg();
         //  payBool = false;
        }
        private void Connetion_CallbackException(object sender, CallbackExceptionEventArgs e)
        {
            Console.WriteLine("Connetion_CallbackException");
            //payMsg();
            payBool = false;
        }

        /// <summary>
        /// 处理事件
        /// </summary>
        /// <param name="json"></param>
        public bool payEvent(object _json)
        {
            string json = (string)_json;
            if (string.IsNullOrEmpty(json)) return true;

            try
            {
                MQReqModel<dynamic> httpReqModel = JsonConvert.DeserializeObject<MQReqModel<dynamic>>(json);

                if (httpReqModel != null && httpReqModel.respEvent == MQEventEnum.Device_Command)
                {
                    MQReqModel<MQSystemCommand> mQReqModel = JsonConvert.DeserializeObject<MQReqModel<MQSystemCommand>>(json);
                    if (mQReqModel.data != null)
                    {
                        Console.WriteLine("\nDevice_Command取值成功！Device_Command");
                        ServiceMQ_SystemCommand.systemProcessStart(mQReqModel);
                    }
                }
                else if (httpReqModel != null && httpReqModel.respEvent == MQEventEnum.Event_HandleCommand)
                {
                    //获取传感器能力

                    Console.WriteLine("\nEvent_HandleCommand MQ取值成功！list");
                    new ServiceHandleCommand().handle(httpReqModel);
                }
                else if (httpReqModel != null && httpReqModel.respEvent == MQEventEnum.Event_Display)
                {
                    //显示器
                    MQReqModel<CommandLogModel> mQReqModel = JsonConvert.DeserializeObject<MQReqModel<CommandLogModel>>(json);
                    if (mQReqModel.data != null)
                    {
                        Console.WriteLine("\nEvent_Display取值成功！显示器  Event_Display");
                        if (mQReqModel.data.deviceModelCode == "1008")
                        {
                            new ServiceDeviceDisplay().executeDisplay1602(mQReqModel);
                        }
                    }
                }
                else
                {
                    //不被支持的指令
                    new ServiceHandleCommand().handleError(httpReqModel);
                }
                Console.WriteLine("--------payEvent处理完成！-----------");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("payEvent： " + ex);
                return false;
            }
        }

        static IConnection connectionSend = null;
        static IModel sendchannel = null;
        public bool sendMsg(string input)
        {

            string queuename = MQEventEnum.MQServer_QueueName;
            try
            {
                //创建连接工厂
                Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss").ToString() + "---- sendmsg推送mq推送上云---------start------- ");
                Console.WriteLine(input);
                Console.WriteLine("----sendmsg推送mq推送上云---------end------------");


                var connectionFactorySend = ServiceRabbitMQ_Common.initFactory();
                if (connectionSend == null || !connectionSend.IsOpen)
                    //创建连接
                    connectionSend = connectionFactorySend.CreateConnection();

                //创建通道
                if (sendchannel == null || !sendchannel.IsOpen)
                {
                    sendchannel = connectionSend.CreateModel();
                    //sendchannel.ExchangeDeclare(EXCHANGE_NAME, EXCHANGE_TYPE, true, false, null);
                    ////声明一个队列
                    //sendchannel.QueueDeclare(queuename, false, false, true, null);
                    //sendchannel.QueueBind(queuename, EXCHANGE_NAME, EXCHANGE_ROUTING_KEY);
                }
                var sendBytes = Encoding.UTF8.GetBytes(input);
                //增加设置消息超时
                IBasicProperties props = sendchannel.CreateBasicProperties();
                props.ContentType = "text/plain";
                props.DeliveryMode = 2;//1（nopersistent）非持久化，2（persistent）持久化
                props.Expiration = "600000";//1000*60*10毫秒 10分钟
                props.Persistent = true;
                //发布消息
                sendchannel.BasicPublish("", queuename, props, sendBytes);
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine("sendMsg Exception： " + ex);
                if (null != sendchannel)
                {
                    sendchannel.Close();
                    sendchannel.Dispose();
                    sendchannel = null;
                }
                if (null != connectionSend)
                {
                    connectionSend.Close();
                    connectionSend.Dispose();
                    connectionSend = null;
                }
                return false;
            }


        }

    }
}
